package MeshlessShapeFunctions;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author mark
 */
public class JCubicSpline implements IKernelFunction{
	
	protected double rho;
	
	public JCubicSpline(double rho){
		this.rho = rho;
	}

    public double evaluateNorm(double x, double y) {
        double xx = Math.abs(Math.sqrt(x*x+y*y));
        if(xx>1){ return 0.0;}
        else{
            if(xx>0.5){
                return 4.0/3.0*Math.pow((1-xx), 3);
            }else{
                return 2.0/3.0 + 4 * ( xx - 1 ) * xx * xx;
            }
        }
    }

    public double evaluateSque(double x, double y) {
        return evaluateNorm(x, 0)*evaluateNorm(0, y);
    }

    public double evaluatePrimeNormX(double x, double y) {
        double xx = Math.abs(Math.sqrt(x*x+y*y));
        if(xx>1){ return 0.0;}
        else{

            if(xx>0.5){
                return 4.0*Math.pow((1-xx), 2)*x/xx;
            }else{
                return 4 * ( 3*xx - 2 ) *x;
            }
        }
    }

    public double evaluatePrimeNormY(double x, double y) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public double evaluatePrimeSqueX(double x, double y) {
        return evaluatePrimeNormX(x, 0)*evaluatePrimeNormX(0, y);
    }

    public double evaluatePrimeSqueY(double x, double y) {
        return evaluatePrimeNormY(x, 0)*evaluatePrimeNormY(0, y);
    }

    public double evaluate(double x) {
        if(Math.abs(x)>1){ return 0.0;}
        else{
            if(Math.abs(x)>=0.5){
                return 4.0/3.0*Math.pow((1-Math.abs(x)), 3);
            }else{
                return 2.0/3.0 + 4 * ( Math.abs(x) - 1 ) * x * x;
            }
        }
    }

    public double evaluateDerivaty(double x) {
        if(Math.abs(x)>1){ return 0.0;}
        else{
            if((x)>=0.5){
                return -4.0*Math.pow((1-x), 2)/rho;
            }
            if((x)<=-0.5){
                return 4.0*Math.pow((1+(x)), 2)/rho;
            }else{
                if(x>=0){
                    return  (12 * ( x*x ) - 8 * x)/rho;
                }else{
                    return  (-12 * ( x*x ) - 8 * x)/rho;
                }
            }
        }
    }
    
    @Override
	public double evaluateSecondDerivaty(double x) {
    	if(Math.abs(x)>1){ return 0.0;}
        else{
            if((x)>=0.5){
                return 8.0*Math.pow((1-x), 1)/rho/rho;
            }
            if((x)<=-0.5){
                return 8.0*Math.pow((1+(x)), 1)/rho/rho;
            }else{
                if(x>=0){
                    return  (24 * ( x ) - 8 )/rho/rho;
                }else{
                    return  (-24 * ( x ) - 8 )/rho/rho;
                }
            }
        }
	}

    public static void main(String[] args){
        double a =-1.5,b=1.5,
        h=0.01;
        double x = a;

        JCubicSpline f  = new JCubicSpline(1);

        while(x<b+h){
            System.out.println(x+"\t"+f.evaluateDerivaty(x));
            x+=h;
        }
    }

	
}
